import { BodyItemConstant } from '../constants/InputItemConstants';
import { CirculatoryDiseasesAdvicesConstants } from '../constants/CirculatoryDiseasesAdvicesConstants';
import adviceJson from './masterdata/CirculatoryDiseasesAdviceMaster.json';
import patternJson from './masterdata/CirculatoryDiseasesPatternMaster.json';
import AdvicesUtils from './CirculatoryDiseasesAdvicesUtils';

export const AdvicesConstants = Object.freeze({

  //体重（ＢＭＩ）アドバイス
  BMI_ADVICES : {
    BMI_GREATER_THAN_25 : 'あなたの体重と身長から計算されるＢＭＩの値は、病気のリスクが高くなる値（25）を超えています。「生活習慣アドバイス」を参考に適正体重に戻していきましょう。',
    BMI_LESS_THAN_25 : 'あなたの体重と身長から計算されるＢＭＩの値は、病気のリスクが高くなる値（25）の範囲内です。「生活習慣アドバイス」を参考にこれからも適正体重を保っていきましょう。',
  },

  // 血糖アドバイス
  BLOOD_SUGAR_ADVICES : {
    EDTL : '血糖値はしっかりコントロールできているようです。これからも、主治医と相談をしながら、血糖のコントロールをしていきましょう。',
    EDTM : '血糖値がやや不良です。治療中ということですので、主治医と相談をしながら、血糖のコントロールをしていきましょう。',
    EDTH : '血糖値がかなり高くなっています。主治医としっかり相談をして、血糖のコントロールができるようにがんばっていきましょう。',
    ND : '血糖値には問題がないようです。他の項目が改善するように生活習慣を見直しながら、血糖値にも注意をしていきましょう。',
    EDUM : '血糖値がやや不良です。生活習慣改善のアドバイスを参考に、生活習慣を見直して血糖値の値を下げていきましょう。',
    EDUH : '血糖値がかなり高くなっています。すぐに病院に行き、医師と相談をすることで、血糖のコントロールができるようになりましょう。',
  },


  // 血圧アドバイス
  BLOOD_PRESSURE_ADVICES : {
    EHTLL : '血圧はしっかりコントロールできているようです。これからも、主治医と相談をしながら、コントロールを続けましょう。',
    EHTLM : '最低血圧が高めになっています。治療を担当している主治医と相談をしながら、コントロールをしていきましょう。',
    EHTLH : '最低血圧がかなり高めになっています。治療を担当している主治医としっかり相談をしながら、コントロールできるように努めましょう。',
    EHTML : '最高血圧が高めになっています。治療を担当している主治医と相談をしながら、コントロールをしていきましょう。',
    EHTMM : '最高血圧と最低血圧が共にやや高めになっています。治療を担当している主治医と相談をしながら、コントロールをしていきましょう。',
    EHTMH : '最低血圧がかなり高めで、最高血圧もやや高めになっています。治療を担当している主治医としっかり相談をしながら、コントロールできるように努めましょう。',
    EHTHL : '最高血圧がかなり高めになっています。治療を担当している主治医としっかり相談をしながら、コントロールできるように努めましょう。',
    EHTHM : '最高血圧がかなり高めで、最低血圧もやや高めになっています。治療を担当している主治医としっかり相談をしながら、コントロールできるように努めましょう。',
    EHTHH : '最高血圧および最低血圧が共に、かなり高めになっています。治療を担当している主治医としっかり相談をしながら、コントロールできるように努めましょう。',
    NH : '血圧には問題がないようです。他の項目が改善するように生活習慣を見直しながら、血圧にも注意をしていきましょう。',
    EHU : '血圧が高くなっています。病院に行き、医師と相談をして血圧のコントロールをしていきましょう。',
  },

  // 血中脂質
  BLOOD_LIPIDS_ADVICES : {
    NONHDL_BAD : '血中脂質（悪玉コレステロール等）の値に問題があるようです。医師や保健師と、治療の必要性や生活習慣改善の改善方法について相談することをお勧めします。',
    NONHDL_GOOD : '血中脂質（悪玉コレステロール等）の値に問題があるようです。「生活習慣アドバイス」を参考に生活習慣改善をして病気のリスク軽減をしていきましょう。',
    GOOD : '血中脂質（悪玉コレステロール等）の値には問題がないようです。「生活習慣アドバイス」を参考に、病気のリスクが高まらない生活を続けてください。',
  },

  // たばこアドバイス
  SMOKING_ADVICES : {
    ES : 'たばこは病気のリスクを高めます。病院の禁煙外来に行くなどして、禁煙にトライしてはいかがでしょうか？',
    NS : 'このまま、たばこを吸わない生活を続けましょう。',
  },
});

const {
  DIABETES_CURE_FLG,
  ANTIHYPERTENSIVE_FLG,
  SMOKING_HABIT,
} = BodyItemConstant;

const {
  BLOOD_SUGAR_FLG,
  NONHDL_FLG,
  HDL_FLG,
  TG_FLG,
  MAX_BLOOD_PRESSURE_FLG,
  MIN_BLOOD_PRESSURE_FLG,
  SUGAR_TOLERANCE_FLG,
} = CirculatoryDiseasesAdvicesConstants;

class CirculatoryDiseasesAdvicesLogic {

  /**
   * BMIアドバイスを取得する
   * @param {number} BMI
   * @returns BMIアドバイス
   */
  static _getBMIAdvices(bmi) {

    // 25以上
    if (bmi >= 25) {
      return {
        bmiId : 'BMI_GREATER_THAN_25',
        bmiAdvices : AdvicesConstants.BMI_ADVICES.BMI_GREATER_THAN_25,
      };

    // 25未満
    } else {
      return {
        bmiId : 'BMI_LESS_THAN_25',
        bmiAdvices : AdvicesConstants.BMI_ADVICES.BMI_LESS_THAN_25,
      };
    }
  }

  /**
   * 血糖値アドバイスを取得する
   * @param {number} diabetesCureFlg         糖尿病の治療の有無
   * @param {number} bloodSugarGrades        血糖の等級
   * @returns 血糖アドバイス
   */
  static _getBloodSugarAdvices(diabetesCureFlg, bloodSugarGrades) {

    // 治療あり
    if (diabetesCureFlg === DIABETES_CURE_FLG.YES.value) {

      // 血糖良好
      if (bloodSugarGrades === BLOOD_SUGAR_FLG.GOOD) {
        return {
          bloodSugarId : 'EDTL',
          bloodSugarAdvices : AdvicesConstants.BLOOD_SUGAR_ADVICES.EDTL,
        };
      }

      // 血糖やや不良
      if (bloodSugarGrades === BLOOD_SUGAR_FLG.SLIGHTLY) {
        return {
          bloodSugarId : 'EDTM',
          bloodSugarAdvices : AdvicesConstants.BLOOD_SUGAR_ADVICES.EDTM,
        };
      }

      // 血糖不良
      return {
        bloodSugarId : 'EDTH',
        bloodSugarAdvices : AdvicesConstants.BLOOD_SUGAR_ADVICES.EDTH,
      };

      // 治療なし
    } else {

      // 血糖良好
      if (bloodSugarGrades === BLOOD_SUGAR_FLG.GOOD) {
        return {
          bloodSugarId : 'ND',
          bloodSugarAdvices : AdvicesConstants.BLOOD_SUGAR_ADVICES.ND,
        };
      }

      // 血糖やや不良
      if (bloodSugarGrades === BLOOD_SUGAR_FLG.SLIGHTLY) {
        return {
          bloodSugarId : 'EDUM',
          bloodSugarAdvices : AdvicesConstants.BLOOD_SUGAR_ADVICES.EDUM,
        };
      }

      // 血糖不良
      return {
        bloodSugarId : 'EDUH',
        bloodSugarAdvices : AdvicesConstants.BLOOD_SUGAR_ADVICES.EDUH,
      };
    }
  }

 /**
   * 血圧アドバイスを取得する
   * @param {number} antihypertensiveFlg           降圧剤
   * @param {number} maxBloodPressureGrades        最高血圧(収縮期)の等級
   * @param {number} minBloodPressureGrades        最低血圧(拡張期)の等級
   * @returns 血糖アドバイス
   */
  static _getBloodPressureAdvices(antihypertensiveFlg, maxBloodPressureGrades, minBloodPressureGrades) {

    // 降圧剤の服用あり
    if (antihypertensiveFlg === ANTIHYPERTENSIVE_FLG.YES.value) {

      // S良好 且つ D良好
      if (maxBloodPressureGrades === MAX_BLOOD_PRESSURE_FLG.S_GOOD &&
          minBloodPressureGrades === MIN_BLOOD_PRESSURE_FLG.D_GOOD) {

        return {
          bloodPressureId : 'EHTLL',
          bloodPressureAdvices : AdvicesConstants.BLOOD_PRESSURE_ADVICES.EHTLL,
        };
      }

      // S良好 且つ Dやや不良
      if (maxBloodPressureGrades === MAX_BLOOD_PRESSURE_FLG.S_GOOD &&
          minBloodPressureGrades === MIN_BLOOD_PRESSURE_FLG.D_SLIGHTLY) {

        return {
          bloodPressureId : 'EHTLM',
          bloodPressureAdvices : AdvicesConstants.BLOOD_PRESSURE_ADVICES.EHTLM,
        };
      }

      // S良好 且つ D不良
      if (maxBloodPressureGrades === MAX_BLOOD_PRESSURE_FLG.S_GOOD &&
          minBloodPressureGrades === MIN_BLOOD_PRESSURE_FLG.D_BAD) {

        return {
          bloodPressureId : 'EHTLH',
          bloodPressureAdvices : AdvicesConstants.BLOOD_PRESSURE_ADVICES.EHTLH,
        };
      }

      // Sやや不良 且つ D良好
      if (maxBloodPressureGrades === MAX_BLOOD_PRESSURE_FLG.S_SLIGHTLY &&
          minBloodPressureGrades === MIN_BLOOD_PRESSURE_FLG.D_GOOD) {

        return {
          bloodPressureId : 'EHTML',
          bloodPressureAdvices : AdvicesConstants.BLOOD_PRESSURE_ADVICES.EHTML,
        };
      }

      // Sやや不良 且つ Dやや不良
      if (maxBloodPressureGrades === MAX_BLOOD_PRESSURE_FLG.S_SLIGHTLY &&
          minBloodPressureGrades === MIN_BLOOD_PRESSURE_FLG.D_SLIGHTLY) {

        return {
          bloodPressureId : 'EHTMM',
          bloodPressureAdvices : AdvicesConstants.BLOOD_PRESSURE_ADVICES.EHTMM,
        };
      }

      // Sやや不良 且つ D不良
      if (maxBloodPressureGrades === MAX_BLOOD_PRESSURE_FLG.S_SLIGHTLY &&
          minBloodPressureGrades === MIN_BLOOD_PRESSURE_FLG.D_BAD) {

        return {
          bloodPressureId : 'EHTMH',
          bloodPressureAdvices : AdvicesConstants.BLOOD_PRESSURE_ADVICES.EHTMH,
        };
      }

      // S不良 且つ D良好
      if (maxBloodPressureGrades === MAX_BLOOD_PRESSURE_FLG.S_BAD &&
          minBloodPressureGrades === MIN_BLOOD_PRESSURE_FLG.D_GOOD) {

        return {
          bloodPressureId : 'EHTHL',
          bloodPressureAdvices : AdvicesConstants.BLOOD_PRESSURE_ADVICES.EHTHL,
        };
      }

      // S不良 且つ Dやや不良
      if (maxBloodPressureGrades === MAX_BLOOD_PRESSURE_FLG.S_BAD &&
          minBloodPressureGrades === MIN_BLOOD_PRESSURE_FLG.D_SLIGHTLY) {

        return {
          bloodPressureId : 'EHTHM',
          bloodPressureAdvices : AdvicesConstants.BLOOD_PRESSURE_ADVICES.EHTHM,
        };
      }

      // S不良 且つ D不良
      return {
        bloodPressureId : 'EHTHH',
        bloodPressureAdvices : AdvicesConstants.BLOOD_PRESSURE_ADVICES.EHTHH,
      };

    // 降圧剤の服用なし
    } else {


      // S良好 且つ D良好
      if (maxBloodPressureGrades === MAX_BLOOD_PRESSURE_FLG.S_GOOD &&
          minBloodPressureGrades === MIN_BLOOD_PRESSURE_FLG.D_GOOD) {

        return {
          bloodPressureId : 'NH',
          bloodPressureAdvices : AdvicesConstants.BLOOD_PRESSURE_ADVICES.NH,
        };
      }

      // 上記以外の場合
      return {
        bloodPressureId : 'EHU',
        bloodPressureAdvices : AdvicesConstants.BLOOD_PRESSURE_ADVICES.EHU,
      };
    }
  }

  /**
   * 血中脂質アドバイスを取得する
   * @param {number} genderValue                性別
   * @param {number} smokingValue               喫煙習慣
   * @param {number} isHypertension             高血圧の判定
   * @param {number} isHypoglycemia             高低血糖の判定
   * @param {number} isGoodHDL                  HDLの判定
   * @param {number} isGoodTG                   TGの判定
   * @param {number} isGoodNonHdl               non_Hdlを判定
   * @returns 血中脂質アドバイス
   */
  static _getBloodLipidsAdvices(genderValue, smokingValue, isHypertension, isHypoglycemia, isGoodHDL, isGoodTG, isGoodNonHdl) {

    // HDL、TG、non-HDLが全部良好の場合
    if (isGoodHDL === HDL_FLG.YES &&
        isGoodTG === TG_FLG.YES &&
        isGoodNonHdl === NONHDL_FLG.YES) {

      return {
        bloodLipidsId : 'GOOD',
        bloodLipidsAdvices : AdvicesConstants.BLOOD_LIPIDS_ADVICES.GOOD,
      };
    }

    // non-HDLが不良の場合
    if (isGoodHDL === HDL_FLG.NO) {
      return {
        bloodLipidsId : 'NONHDL_BAD',
        bloodLipidsAdvices : AdvicesConstants.BLOOD_LIPIDS_ADVICES.NONHDL_BAD,
      };
    }

    // 上記以外の場合、non-HDLが良好で、HDL、TGのうち１つ以上が不良
    return {
      bloodLipidsId : 'NONHDL_GOOD',
      bloodLipidsAdvices : AdvicesConstants.BLOOD_LIPIDS_ADVICES.NONHDL_GOOD,
    };
  }

  /**
   * たばこアドバイスを取得する
   * @param {number} smokingValue               喫煙習慣
   * @returns たばこアドバイス
   *
   */
  static _getSmokingAdvices(smokingValue) {

    // 喫煙あり
    if (smokingValue === SMOKING_HABIT.IS_SMOKING.value) {
      return {
        smokingId : 'ES',
        smokingAdvices : AdvicesConstants.SMOKING_ADVICES.ES,
      };
    }

    // 喫煙なし
    return {
      smokingId : 'NS',
      smokingAdvices : AdvicesConstants.SMOKING_ADVICES.NS,
    };
  }

  /**
   * マスタからすすめの生活習慣の内容を取得する
   * @param {number} key 抽出キー(すすめの生活習慣のID)
   * @return すすめの生活習慣の内容
   */
  static _getRecommendationContent(key) {

    // すすめの生活習慣の内容
    const title = ['<div style="color:#0e7cdc;font-size:28px;text-align:center;font-weight:bold;"><p>おすすめ　その１</p></div>', '<div style="color:#0e7cdc;font-size:28px;text-align:center;font-weight:bold;"><p>おすすめ　その２</p></div>', '<div style="color:#0e7cdc;font-size:28px;text-align:center;font-weight:bold;"><p>おすすめ　その３</p></div>\n'];
    const pattern = adviceJson[key].split(' ');
    let advice = '';

    for (let i = 0, n = pattern.length; i < n; i++) {
      advice += title[i];
      advice += patternJson[pattern[i]];
    }

    return advice.replace(/,/g, '');
  }

  /**
   * すすめの生活習慣のIDを取得する
   * @param {number} isGoodHDL                  HDLの判定
   * @param {number} isGoodTG                   TGの判定
   * @param {number} isGoodNonHdl               non_Hdlを判定
   * @param {number} triglyceride               中性脂肪
   * @param {number} bmi                        BMI
   * @param {number} smokingValue               喫煙習慣
   * @param {number} isHypertension             高血圧の判定
   * @param {number} diabetesCureFlg            糖尿病の治療の有無
   * @param {number} SugartoleranceGrades       血糖の等級
   * @returns すすめの生活習慣のID
   */
  static _getRecommendationId(isGoodHDL, isGoodTG, isGoodNonHdl, triglyceride, bmi, smokingValue, isHypertension, diabetesCureFlg, SugartoleranceGrades) {

    // 特別処理
    // HDL良好（40≦HDL-C）且つ TG良好（TG<150）且つ non-HDL良好
    if (isGoodHDL === HDL_FLG.YES &&
        isGoodTG === TG_FLG.YES &&
        isGoodNonHdl === NONHDL_FLG.YES) {

      // 糖尿病治療なし
      if (diabetesCureFlg === DIABETES_CURE_FLG.NO.value) {

        // 耐糖能異常なし
        if (SugartoleranceGrades === SUGAR_TOLERANCE_FLG.GOOD) {
          return 'NLDUL';
        }

        // 耐糖能異常あり（I）
        if (SugartoleranceGrades === SUGAR_TOLERANCE_FLG.SLIGHTLY) {
          return 'NLDUM';
        }

        // 耐糖能異常あり（A）
        return 'NLDUH';
      }

      // 糖尿病治療あり
      return 'NLDT';

    }

    // 脂質基準対応するIDを取得する
    const lipidStandardId = AdvicesUtils._getLipidStandardId(isGoodHDL, isGoodTG, isGoodNonHdl, triglyceride);
    // 肥満・喫煙・血圧対応するアドバイスIDを取得する
    const obeseSmokeBPressureId = AdvicesUtils._getObeseSmokeBPressureId(bmi, smokingValue, diabetesCureFlg, isHypertension);
    // 血糖基準対応するIDを取得する
    const bloodSugarStandardId = AdvicesUtils._getBloodSugarStandardId(diabetesCureFlg, SugartoleranceGrades);

    // すすめの生活習慣のID
    return lipidStandardId + '_' + obeseSmokeBPressureId + '_' + bloodSugarStandardId;
  }
}

export default CirculatoryDiseasesAdvicesLogic
